package com.yuyou.weixin.util;

import org.apache.commons.lang3.time.DateUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by wens on 16-7-22.
 */
public class TimeUtils {


    public static String prettyTime(long off) {

        off = off / 1000;
        if (off < 60) {
            return off + "秒";
        }

        off = off / 60;

        if (off < 60) {
            return off + "分钟";
        }

        off = off / 60;

        if (off < 24) {
            return off + "小时";
        }

        return off / 24 + "天";


    }

    public static Date now() {
        return new Date();
    }

    public static Date nowDate() {
        Calendar instance = Calendar.getInstance();
        instance.set(Calendar.MILLISECOND, 0);
        instance.set(Calendar.SECOND, 0);
        instance.set(Calendar.MINUTE, 0);
        instance.set(Calendar.HOUR, 0);
        return instance.getTime();
    }

    /**
     * 时间转换格式
     *
     * @param date
     * @return
     */
    public static String date2String(Date date) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String strDate = sdf.format(date);
            return strDate;
        }
        return null;
    }

    public static String date2String(Date date, String format) {
        if (date != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            String strDate = sdf.format(date);
            return strDate;
        }
        return null;
    }

    public static Date parse(String src, String format) {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(src);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /* 两个日期相隔天数 */
    public static int daysOfTwo(Date fDate, Date oDate) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            fDate = sdf.parse(sdf.format(fDate));
            oDate = sdf.parse(sdf.format(oDate));
        } catch (Exception e) {

        }

        Calendar cal = Calendar.getInstance();
        cal.setTime(fDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(oDate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }


    /**
     * 获取当前日期是星期几<br>
     *
     * @param dt
     * @return 当前日期是星期几
     */
    public static int getWeekOfDate(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return w;
    }

    public static boolean isOverlap(String startdate1, String enddate1, String startdate2, String enddate2, String timeFormat) {
        SimpleDateFormat format = new SimpleDateFormat(timeFormat);
        Date leftStartDate = null;
        Date leftEndDate = null;
        Date rightStartDate = null;
        Date rightEndDate = null;
        try {
            leftStartDate = format.parse(startdate1);
            leftEndDate = format.parse(enddate1);
            rightStartDate = format.parse(startdate2);
            rightEndDate = format.parse(enddate2);
        } catch (ParseException e) {
            return false;
        }
        return ((leftStartDate.getTime() >= rightStartDate.getTime()) && leftStartDate.getTime() < rightEndDate.getTime())
                || ((leftStartDate.getTime() > rightStartDate.getTime())
                && leftStartDate.getTime() <= rightEndDate.getTime())
                ||
                ((rightStartDate.getTime() >= leftStartDate.getTime())
                        && rightStartDate.getTime() < leftEndDate.getTime())
                ||
                ((rightStartDate.getTime() > leftStartDate.getTime())
                        && rightStartDate.getTime() <= leftEndDate.getTime());

    }

    // 给定两个日期（string），遍历之间的所有日期
    public static List<String> queryData(String startAt, String endAt) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dates = new ArrayList<>();
        try {
            Date startDate = dateFormat.parse(startAt);
            Date endDate = dateFormat.parse(endAt);
            dates.addAll(queryData(startDate, endDate));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dates;
    }

    public static List<String> queryData(Date startAt, Date endAt) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> dates = new ArrayList<>();
        Calendar start = Calendar.getInstance();
        start.setTime(startAt);
        Calendar end = Calendar.getInstance();
        end.setTime(endAt);
        while (start.before(end) || start.equals(end)) {
            dates.add(dateFormat.format(start.getTime()));
            start.add(Calendar.DAY_OF_YEAR, 1);
        }
        return dates;
    }

    public static BigDecimal hoursCounting(String startDate, String endDate, String startTime, String endTime, String dateFormat, String timeFormat) {
        Date date1 = parse(startDate, dateFormat);
        Date date2 = parse(endDate, dateFormat);
        BigDecimal hours1 = hoursOfTwo(date1, date2);
        Date time1 = parse(startTime, timeFormat);
        Date time2 = parse(endTime, timeFormat);
        BigDecimal hours2 = hoursOfTwo(time1, time2);
        return hours1.add(hours2);
    }

    // 相隔小时数
    private static BigDecimal hoursOfTwo(Date time1, Date time2) {

        long diff = time2.getTime() - time1.getTime();
        BigDecimal hours = new BigDecimal(diff).divide(new BigDecimal(3600000), 2, BigDecimal.ROUND_HALF_UP);
        return hours;
    }

    /**
     * 时间运算
     *
     * @param date  时间
     * @param field 需要加减的属性
     */
    public static Date operation(Date date, int field, int amount) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(field, amount);
        return calendar.getTime();
    }

    public static BigDecimal countHourNum(String startStr, String endStr) {
        Date start = Utils.parseDate(startStr, "HH:mm");
        Date end = Utils.parseDate(endStr, "HH:mm");
        BigDecimal result = BigDecimals.toFixed2(new BigDecimal((double) (end.getTime() - start.getTime()) / 1000 / 60 / 60), 2);
        return result;
    }

    /*public static void main(String[] art) throws Exception {


        List<Long> sd = new ArrayList<>();
        sd.add(1L);
        sd.add(2L);
        if (sd.contains(1l)) {
            System.out.println("sdfdsf");
        }

        String stal = "08:00";
        String as = "09:40";
        BigDecimal sssaga = countHourNum(stal, as);


        int days1r5 = daysOfTwo(new Date(), new Date());
        Integer agat = 7;
        Integer agahh = 1;
        agahh = agahh / agat + agahh % agat;

        List<String> afa = new ArrayList<>();
        afa.add("a");
        afa.add("b");
        List<String> afa1 = new ArrayList<>();
        afa1.add("a");
        afa1.add("b1");

        List<String> agage = afa;
        agage.retainAll(afa1);

        String ssl1 = "2017-02-28";
        Date dates = Utils.parseDate(ssl1, "yyyy-MM-dd");

        Date saga = addYearByNum(dates, 1);

        BigDecimal tsth = BigDecimal.ZERO;
        if (tsth.equals(BigDecimal.ZERO)) {
            System.out.println("fsd");
        }

        String ssl = "2016";
        String ss2 = "2019";
        Integer inte = Integer.parseInt(ss2);
        Integer ssssf = Integer.parseInt(ssl);
        while (ssssf <= inte) {
            System.out.println(ssssf.toString());
            ssssf = ssssf + 1;
        }
        System.exit(0);


        int days = daysOfTwo(new Date(), new Date());

        BitSet ts = new BitSet();
        ts.set(20, 100);
        System.out.println(ts.toString());
        BitSet ss = (BitSet) ts.clone();
        ts.set(100, 120);
        System.out.println(ts.toString());
        System.out.println(ss.toString());

        String test1 = "2017-09-02 24:00";
        Date ddddd = Utils.parseDate(test1, "yyyy-MM-dd HH:mm");
        System.out.print(toMini(ddddd));


        String test2 = "2017-09-19";
        String test3 = "2017-09-19";
        String test4 = "2017-10-28";
        String test6 = "2014-09-01";
        String test7 = "2017-10-28";
        BitSet bitSettest = new BitSet();
        bitSettest.set(TimeUtils.toMini(Utils.parseDate(test1, "yyyy-MM-dd")), TimeUtils.toMini(Utils.parseDate(test2, "yyyy-MM-dd")));
        bitSettest.set(TimeUtils.toMini(Utils.parseDate(test3, "yyyy-MM-dd")), TimeUtils.toMini(Utils.parseDate(test4, "yyyy-MM-dd")));


        BitSet bitSet = new BitSet();
        bitSet.set(TimeUtils.toMini(Utils.parseDate(test6, "yyyy-MM-dd")), TimeUtils.toMini(Utils.parseDate(test7, "yyyy-MM-dd")));

        System.out.println(bitSet.cardinality());
        bitSet.andNot(bitSettest);
        System.out.println(bitSet.cardinality());


        String s1 = "2017-08-02 12:33:01";
        String s2 = "2017-08-02 13:33:00";

    }*/

    public static String getLastDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        // 设置年份
        cal.set(Calendar.YEAR, year);
        // 设置月份
        cal.set(Calendar.MONTH, month - 1);
        // 获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        // 设置日历中月份的最大天数
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        // 格式化日期
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String lastDayOfMonth = sdf.format(cal.getTime());

        return lastDayOfMonth;
    }

    public static Date changeDateByNum(Date date, int num) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(Calendar.DAY_OF_MONTH, num);
        return cal.getTime();
    }

    class Test<T> {
        private T one;

    }

    public static boolean isOverlap(Date startDate1, Date endDate1, Date startDate2, Date endDate2) {
        Date leftStartDate = startDate1;
        Date leftEndDate = endDate1;
        Date rightStartDate = startDate2;
        Date rightEndDate = endDate2;

        return ((leftStartDate.getTime() >= rightStartDate.getTime()) && leftStartDate.getTime() < rightEndDate.getTime())
                || ((leftStartDate.getTime() > rightStartDate.getTime())
                && leftStartDate.getTime() <= rightEndDate.getTime())
                ||
                ((rightStartDate.getTime() >= leftStartDate.getTime())
                        && rightStartDate.getTime() < leftEndDate.getTime())
                ||
                ((rightStartDate.getTime() > leftStartDate.getTime())
                        && rightStartDate.getTime() <= leftEndDate.getTime());

    }

    public static int toMini(Date date) {
        return (int) (date.getTime() / 1000 / 60 - 23667360l/*2015-01-01*/);
    }

    public static String miniRevert(Integer timeStamp) {
        Long realTimeStamp = (timeStamp.longValue() + 24720000l) * 60 * 1000;
        Date date = new Date();
        date.setTime(realTimeStamp);
        return Utils.formatDate(date, "yyyy-MM-dd HH:mm");
    }


    public static Date startOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date endOfDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    public static int durationOfDay(Date d1, Date d2) {

        if (d1.after(d2)) {
            Date t = d1;
            d1 = d2;
            d2 = t;
        }

        int cnt = 1;

        while (!DateUtils.isSameDay(d1, d2)) {
            cnt++;
            d1 = DateUtils.addDays(d1, 1);
        }
        return cnt;
    }

    public static Date firstDateOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, 1);
        Date startDate = c.getTime();
        return startDate;
    }

    public static Date lastDateOfMonth(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date endTime = c.getTime();
        return endTime;
    }

    public static Date addMonthByNum(Date date, int monthNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.MONTH, monthNum);
        return c.getTime();
    }

    public static Date addYearByNum(Date date, int yearNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.YEAR, yearNum);
        return c.getTime();
    }

    public static Date changeOneDateLastTime(Date date) {
        String str = Utils.formatDate(date, "yyyy-MM-dd") + " 23:59:59";
        return Utils.parseDate(str, "yyyy-MM-dd HH:mm:ss");
    }

    public static Date changeSecond(Date date, int secondNum) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.add(Calendar.SECOND, secondNum);
        return c.getTime();
    }

}
